筆記、[NET101] 網路基礎概論 (1)


Posted by s103071049 on 2021-05-03

前言 : 網路的目的在於溝通,傳紙條的目的也在於溝通。

  • 傳紙條故事第一集(告白篇) :
    結論 : 傳紙條需要 (1) 寫明來源 (2) 寫明目的地 (3) 經過三次前置作業,確保雙方都能收發。

  • 傳紙條故事第二集(便當篇) :
    小明小美愛的故事,啟發了有生意頭腦的千千,千千開啟了代訂便當之路,但在代訂過程中有了這些困擾

(一)、 數字格式不統一 ( 3個便當、THREE排骨飯、參個G肉...),故需將格式統一。

(二)、特殊需求(辣椒加到爆、第四堂課送到體育館前...),特殊需求少時還可以,特殊需求多就可以將其歸類,以便作業流程,可以將紙條分成兩部分,header (額外特殊資訊,如 : 送達時間-第四堂、辣椒-多)、body (傳送主要資訊,如 : 雞腿飯 5 、牛肉麵 3 、排骨便當 4 ),利用這樣的方式擴充性可以大幅提升,如需要增加免洗筷,就在 header,再增加選項。

(三)、 一個一個打字太累了,所以千千提供訂便當回傳代碼對照表,並且將回傳內容也分成 header (狀態400) 、body (你第三行字太醜,看不懂)。

(四)、 動作不統一。除了訂便當外,同學們還會透過傳紙條做其他事情,例如 : 不想訂購便當、更改便當內容、每隔十分鐘問一次便當甚麼時間來。所以千千針對這些動作制定標準(在 header 裡面附上動詞,如 : get 想知道訂單資訊、 post 我要訂便當、 delete 取消訂單、 put 修改訂單)。

所以藉由(一)~(四)標準化後,對於新來的同學也可以很容易知道如何處理訂單。
結論 : 傳紙條需要 (1) 標準化內容格式 (2) 分成 header(額外附加資訊)、body(主要資訊) (3) 用狀態碼標準化結果 (4) 用動詞標準化動作

  • 傳紙條故事第三集(發大財篇) :
    千千不想只靠賣便當賺大錢,千千進了各式不同服務,所以現在 TO :八班千千,後面還需要寫明你要的服務,如 : 訂便當、訂飲料...。千千會在收到需求後(不同的服務型態),將紙條內容轉給他的同學們,然後讓班級一起發大財。但要注意,為了不打架、好分工、分薪水,一個同學只負責一個服務。

擴大生意規模,千千碰到的問題以及可以優化的部分(如 : 標準化)

(一)、 標準化 : 統一服務代碼,不用再寫訂飲料三個字,只要寫服務代碼。故千千提供了服務代碼對照表。

(二)、 簡化格式 : 訂便當會有很多狀況,但借籃球只有借與不借,所以不同服務內容可以有不同的格式,所以千千決定依據的服務內容決定最洽當的格式是什麼樣子。

(三)、 加快速度 : 有些地方不需要經過三次作業確認收發狀態,例如 : NBA 及時戰況,有此需求同學找千千訂閱,每隔五~十秒鐘,千千就把及時戰況的分數傳給你,在這項服務中不需要做到確認的工作,因為每隔五秒就傳一張,所以就算中間漏了一兩張,對整體的戰局不影響,這項服務的重點在於及時性而不是訊息的穩定性。如果需要確認的話,每張訊息就要再多三次傳紙條動作,會拖慢速度。

(四)、 不知不覺這項服務風靡全台灣,現在可以將這張紙條傳到其他學校,(過去 = FROM 一班雜魚 TO 八班千千:3000),(現在= FROM 芭樂國中一班雜魚 TO 鳳梨國中八班千千:3000),大部分郵差很厲害可以看到地標就把信傳過去,極少部分郵差看不懂(外國人),所以寫地址其實最保險,當然寫地標也可以。

結論 : 傳紙條需要 (1) 新增服務代後,一人負責一個服務 (2) 不同服務可以有不同的格式,不一定要遵守同一套格式 (3) 有些服務不一定需要經過三次確認 (4) 跨校傳紙條寫校名不寫地址也可以

一、為甚麼我們需要協定(protocol)

協定是一個為了讓彼此可以溝通而制定的規範。例如 : 到國外商店買東西,不會講當地語言,老闆會拿計算機出來打數字,因為彼此都理解阿拉伯數字,所以可以藉由這樣的方式進行溝通。這個規範會有一些標準,有了標準才可以做規模化。協定需要足夠完整,才能涵蓋各式場景。

二、由上到下:從 HTTP 協定開始講起

前言 : 我們要了解 http 這套協定在做什麼(答=網頁前端、網頁後端的溝通)、日常生活和這個協定的那些部分是有關連(答=平常上網和 server 做溝通),所以網址前面會是 http、s 是 secure 更安全的意思。另外我們可以想像了解 http 這套協定,就和了解千千的訂便當協定是一樣的。

(一)、http request 的一生

背景知識 : 透過協議溝通的兩端,可以分成 client(我的電腦、瀏覽器、訂便當的同學) 、 server

流程 :

  1. 瀏覽器製造 http request 傳給 server, server 經過處理後再傳 response 回來
  2. 雜魚寫紙條傳給千千,千千經過處理再將紙條傳給雜魚

結論 : 本質為傳東西過去、傳東西回來,所以重點是這個東西的格式長什麼樣子

(二)、 我只是個計程車司機:DNS Server (Domain Name System)

前言 :
回憶傳紙條例子,風靡全台時,寫明地標郵差就知道位置在哪。同網路運作,我們的 url 是一串網址,背後是有機制將其轉換成 IP 位置。 DNS server 就是負責處理 domain name 與實際 IP 位置轉換,可以想像成坐計程車,我們告訴司機要去台北一零一,司機會自動轉換(台北市信義區信義路五段7號89樓)。實際上電腦最底層是把 request 送到 IP 位置。可以在 cml 透過nslookup 網址查詢這個Domain Name 對應到的 IP 位置是哪裡,可能會有多個結果,對應到多個 server 。

小時候安裝盜版軟體,通常會要求改 hosts 檔案,會要求把一個很奇怪的 domain 對應到 127.0.0.4。 host database ,可以把一個 domain name 對應到一個 IP 位置。比方說,我現在要發送一個 request 到 local host (127.0.0.4),local host 算是一個 domain 所以它會對應到哪裡 ? 電腦會先去 host database 查,然後返回 (127.0.0.4),所以如果我在檔案中新增了 127.0.0.4 github.com ,所以當我在瀏覽器輸入 github.com 時,電腦就會把 github.com 的 IP 位置解析成 127.0.0.1 。通常在測試上會用到 hosts 檔案,另外 (127.0.0.4) 是一個特殊的 IP 位置,表示自己的電腦。

所以現在回到小時候的盜版軟體,它的原理:
request => adobe.com => response ,
request => ?? => xxx 現在他的request被送到一個奇怪的地方,它就不會有任何回應,它的檢查就會失敗,所以可能就不會把這個視作盜版。

結論 : DNS 是把 domain name 轉換成 IP,電腦在送出 request 時會先在本地端 host database 配對一些規則,然後才去 DNS server 查這件事情

(三)、永遠不要忘記瀏覽器只是另一個程式

意思是說,我們沒有瀏覽器仍然可以拿到 response 。我們可以透過 request simplified

const request = require('request');
request('http://www.google.com', function (error, response, body) {
  console.error('error:', error); // Print the error if one occurred
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage. 回傳的 body 是我們透過 request library 從 server 上拿到的內容,也就是這個 server 回傳的 response
});

結論 :瀏覽器能做到的,我們寫程式也可以做到。瀏覽器只是幫助我處理這些事情。 脫離瀏覽器我們還是可以發 request 到 server 然後拿到 response 。瀏覽器上會有一些限制,但自己寫程式是可以跳過這些限制。

(四)、Header 與 Body(不是網頁的那個)

回憶傳紙條故事, Header 是傳額外資訊, Body是傳主要內容。request 、response都有分成兩個部分,Header 與 Body

結論 : request 與 response 都分成 Header 與 Body 分別帶著不同的資訊。

(五)、HTTP method

回憶傳紙條故事,我們加上動詞決定要執行什麼動作,EX : GET、POST......,實際上 http 的 request 也是如此。HTTP method 請求方法

  1. get : 只用於取得資料。如 : 我發一個 get request 到這個地方去,看他 response 是什麼,再顯示回來給我。 (比較) HEAD 只用來拿 response 的 header 不拿 body,應用在我只想知道檔案的資訊,可是我不想知道內容。

  2. post : 提交東西、狀態。form data 可以檢視 post 裡面夾帶的資訊,裡面有 key、value 的相對。view source 是在 request 內,它會經過一些編碼。所以在 post 的時候就有 request body (你想要的資訊是什麼,例如 : 五個雞腿飯、兩個排骨飯)。

  3. put : 改變資源。(比較) PATCH , PUT 會取代掉所有東西,例如 : 訂單為五個雞腿飯、兩個排骨飯,現在用 PUT 放十個排骨飯,則我的訂單會變成十個排骨飯;PACH 指定資源的部分修改,承上用 PATCH 放十個排骨飯,則我的訂單會變成五個雞腿飯、十個排骨飯。因為兩種用法很像,實務上會看別人提供的文件,決定用法。

  4. delete : 刪除指定資源。

  5. options : 回傳這個 server 支援了那些方法。

結論 : 常用方法為 get 、 post 、 put 、 patch、delete

(六)、HTTP Status code

通常以開頭區分,1 開頭=用戶端要進行一些處理,2 開頭=成功,如 : 200 (ok)、3 開頭=重新導向,如 : 301 (永久被移到新的位置) /302 (暫時移到新的位置)、4開頭=用戶端錯誤,如 : 404 (not found) 、5 開頭 = 伺服器出錯,如 : 搶票系統死當。

1xx hold on
2xx here you go
3xx go away
4xx you fucked up
5xx I fucked up

結論 : 1、2、3、4、5,狀態要記

(七)、實作一個超簡易 HTTP Server

檢視實做結果 : http://localhost:5000/ ,我們也可以拜訪不同的,它的 /url 就會不同。所以我們可以根據不同的 req.url 做不同的事情,server 端會根據不同的網址,給出不同的回應。
結論 : 依據 req 的資源,決定給予的 response、需要有 header與status code 的知識才知道回什麼資訊

var http = require('http')// 內建函式
// 怎麼處理裡面的資訊,A=傳一個function進去
var server = http.createServer(function (req, res) {
  console.log(req.url)
  res.write('hello') //回傳什麼資訊回去
  res.end()

}) 

server.listen(5000)// 再給一個port的名稱,port類似千千事業的服務代碼

// 顯示結果

/*
$ node index.js
/ 根目錄
/favicon.ico 網頁左上角的小 icon ,這是瀏覽器預設會發的 req
*/
var http = require('http')// 內建函式
// 怎麼處理裡面的資訊,A=傳一個function進去
var server = http.createServer(function (req, res) {
 if (req.url === '/') {
    res.write('welcome')
    res.end()
    return
 }

 if (req.url === '/hello') {
    res.write('hello')
    res.end()
    return
 }
 if (req.url === '/redirect') {
    // 第一個參數是回傳狀態碼,後面是 header 要放的東西
    res.writeHead(302, {
        'lidemy' : 'good',
        'Location':'/hello' // 轉值到該去的位置
    })
    res.end()
    return
 }
 res.writeHead(404)
 res.end() // 沒有 end client端會不知道這個要結束了
 //return

}) 

server.listen(5000)// 再給一個port的名稱,port類似千千事業的服務代碼

// 如果出現一直等待的狀態,表示代碼沒有寫好

#HTTP #get #post #HTTP method







Related Posts

實作一個 ChatGPT 打字機效果 request - EventSource

實作一個 ChatGPT 打字機效果 request - EventSource

「三元運算子」不好嗎?

「三元運算子」不好嗎?

寫一個簡單堪用的 ESLint plugin

寫一個簡單堪用的 ESLint plugin


Comments